Skip to content

Conversation

@francesco-carrella
Copy link

Add trace correlation, breadcrumbs, and structured logging to Sentry sink

Summary

Adds observability features to @logtape/sentry for distributed systems debugging:

  • Automatic trace correlation (trace_id/span_id from active spans)
  • Optional breadcrumbs (debugging context trail)
  • Configurable event levels
  • Structured logging support (Sentry Logs API v9.41.0+)
  • beforeSend hook for filtering/transformation
  • Modern Sentry v8+ API pattern

Impact: ~270 LOC, 100% backward compatible, zero new dependencies

Why

The current @logtape/sentry integration (v1.1.x) works correctly but lacks observability features needed for distributed systems. When using LogTape with Sentry's tracing and performance monitoring, there's no way to correlate logs with traces, no debugging context trail via breadcrumbs, and messages with dynamic values create separate issues instead of grouping together.

This PR addresses these gaps while maintaining backward compatibility and cross-runtime support.

Compliance with Sentry Guidelines

This implementation follows official Sentry SDK development guidelines:

Uses Global Functions (Not Multiple Clients)

Following Sentry Best Practices, which state:

"Creating multiple Sentry clients is not recommended in general, as it can lead to unexpected behavior."

The sink uses global Sentry functions (captureMessage, captureException, getActiveSpan) instead of client instances. The v1.1.x client-based pattern is deprecated but remains functional for backward compatibility.

Logging Protocol Compliance

Implements features from Sentry SDK Logging Protocol:

  • Trace Association: Automatically captures trace_id/span_id from active spans (lines 304-312)
  • enableLogs Support: Auto-detects SDK 9.41.0+ and enableLogs: true configuration (lines 327-340)
  • beforeSend Hook: Provides log filtering/transformation capability (lines 283-286)
  • Default Attributes: Includes sentry.origin, category, timestamp (lines 296-301)

JavaScript Logging Standards

Meets requirements from Sentry JavaScript Logs Documentation:

  • Minimum SDK version 9.41.0 for structured logging
  • Graceful degradation for older SDK versions
  • Proper log level mapping
  • Automatic attribute enrichment

Feature Comparison

Comparison with other Sentry logging integrations:

Feature Pino Transport Winston Community LogTape (this PR)
Structured Logging Yes No Yes
Trace Correlation No No Yes (automatic)
Breadcrumbs No Manual only Yes (automatic)
Message Grouping No No Yes (ParameterizedString)
beforeSend Hook No No Yes
Error Detection Basic Basic Smart (Error property)
Cross-Runtime Node only Node only Deno/Node/Bun/Edge

Reference: Based on official Pino transport and community Winston transports.

What Changed

1. Automatic Trace Correlation (lines 304-312)

Captures trace_id, span_id, and parent_span_id from active Sentry spans. Always enabled with zero overhead if no active span exists. Uses Sentry v8+ getActiveSpan() API.

2. Optional Breadcrumbs (lines 315-324)

Adds logs as breadcrumbs to provide debugging context trail. Opt-in via enableBreadcrumbs: true.

getSentrySink({ enableBreadcrumbs: true });

3. Structured Logging Support (lines 327-340)

Automatic support for Sentry's Logs API (v9.41.0+). Users enable it in their Sentry config:

Sentry.init({ dsn: "...", enableLogs: true });

Uses _INTERNAL_captureLog (same approach as official Pino transport). Public wrapper APIs are in development (#15717).

Note: The official Pino transport only supports structured logging. This PR adds trace correlation, breadcrumbs, message grouping, and events support.

4. Enhanced Event Capture (lines 343-358)

Configurable event levels with special error handling. If log includes error property with Error instance, uses captureException for better stack traces.

getSentrySink({
  captureAsEvents: ["error", "fatal"],
  beforeSend: (record) => record  // Optional filter
});

5. Modern Sentry v8+ API Pattern (lines 272-278)

Uses global functions instead of client instances, following Sentry Best Practices:

// v1.2.0 (recommended)
getSentrySink();

// v1.1.x (deprecated but still works)
getSentrySink(getClient());

6. Additional Enhancements

  • Enriched attributes: Adds sentry.origin, category, timestamp
  • Level mapping: Consistent across events, breadcrumbs, and logs
  • ParameterizedString: Preserves template structure for message grouping
  • Error handling: Sink never throws

API

export interface SentrySinkOptions {
  enableBreadcrumbs?: boolean;      // Default: false
  captureAsEvents?: string[];       // Default: ["error", "fatal"]
  beforeSend?: (record: LogRecord) => LogRecord | null;
}

export function getSentrySink(
  optionsOrClient?: SentrySinkOptions | SentryInstance
): Sink

Backward compatibility: Existing code continues to work unchanged. Client parameter shows deprecation warning but remains functional.

Impact

  • Logs automatically correlate with traces when using Sentry performance monitoring
  • Breadcrumb trail shows what happened before errors
  • Messages with dynamic values group correctly in Sentry UI
  • No breaking changes; all existing LogTape + Sentry setups continue to work
  • Cross-runtime support maintained for Deno, Node.js, Bun, browsers, and edge functions

Quality

  • Type checking passes (deno check)
  • Linting passes (deno lint)
  • Formatting passes (deno fmt)
  • Manual testing with real Sentry project (verified breadcrumbs, trace correlation, structured logs)
  • Verified across Sentry SDK versions: v8.0, v9.41, v10.16
  • Verified across runtimes: Node.js, Deno
  • No unit tests added (following existing @logtape/sentry pattern - Sentry SDK difficult to mock meaningfully)

Files Changed

M  packages/sentry/src/mod.ts          (+342 lines - implementation)
M  packages/sentry/README.md           (minimal README)
M  docs/manual/sinks.md                (+243 lines - comprehensive documentation)
M  packages/sentry/deno.json           (version bump prep)
M  packages/sentry/package.json        (dependencies)
M  CHANGES.md                          (changelog)
M  deno.lock                           (dependency lock)
M  pnpm-lock.yaml                      (npm lock)

Dependencies: None added. Uses existing @sentry/core and @logtape/logtape.

Questions for Review

  1. Should breadcrumbs default to true or false? (Currently false to avoid noise)

@gemini-code-assist
Copy link

Summary of Changes

Hello @francesco-carrella, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly upgrades the @logtape/sentry integration by introducing advanced observability features essential for modern distributed systems. The changes enable automatic correlation of logs with Sentry traces, provide optional breadcrumbs for a clearer debugging context, and add robust structured logging capabilities. These enhancements aim to streamline debugging workflows and improve log grouping within Sentry, all while maintaining full backward compatibility and broad runtime support.

Highlights

  • Enhanced Observability Features: The Sentry sink now includes automatic trace correlation, optional breadcrumbs, and structured logging support for improved debugging in distributed systems.
  • Modern Sentry API Adoption: The getSentrySink() function has been updated to use Sentry's global functions, aligning with Sentry v8+ best practices. Direct client passing is now deprecated but remains functional with a warning.
  • Configurable Event Capture: Introduced a captureAsEvents option to specify which log levels should be captured as full Sentry events, defaulting to error and fatal.
  • Structured Logging and Message Grouping: Automatic support for Sentry's Logs API (SDK v9.41.0+ with enableLogs: true) is included, along with ParameterizedString support for better message grouping in the Sentry UI.
  • Flexible Log Processing: A beforeSend hook has been added, allowing users to transform or filter log records before they are sent to Sentry.
  • Backward Compatibility and Cross-Runtime Support: All new features are backward compatible, and the sink continues to support Deno, Node.js, Bun, browsers, and edge functions.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request significantly enhances the @logtape/sentry sink by adding modern observability features like trace correlation, breadcrumbs, and structured logging. The implementation is well-structured and follows Sentry's best practices. My review focuses on a correctness issue in the backward-compatibility layer that affects message grouping, and a small refactoring opportunity to improve code clarity. Overall, this is a great contribution that brings valuable features to the Sentry integration.

@francesco-carrella francesco-carrella marked this pull request as draft October 2, 2025 15:02
The Sentry sink now provides comprehensive observability features for
production debugging, including automatic trace correlation, breadcrumbs,
and structured logging support via Sentry's Logs API.
- Add automatic trace context capture from active Sentry spans (trace_id, span_id)
- Add enableBreadcrumbs option to create breadcrumbs for debugging context
- Add captureAsEvents option to control which log levels become Sentry events
- Add automatic structured logging support (Sentry SDK v9.41.0+ with enableLogs: true)
- Add ParameterizedString support for better message grouping in Sentry
- Add beforeSend hook for transforming/filtering records
- Modernize API to use global Sentry functions (v8+ pattern)
- Maintain backward compatibility with v1.1.x client-based pattern
@francesco-carrella francesco-carrella force-pushed the feature/sentry-scope-integration branch from 352990a to 4efa09e Compare October 2, 2025 15:15
@dahlia
Copy link
Owner

dahlia commented Oct 4, 2025

Could you update the lockfile?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants